import java.util.ArrayList;
import java.util.regex.Pattern;

public class db_statement_create_table implements db_interface_statement {

	public String[] oTokens = new String[27];
	public Pattern[] oRegex = new Pattern[3];
	private db_util_parser oUtilParser = null;
	private db_parse_result_create_table oRes = null;
	private ArrayList<db_column> oColumns = null;
	private int iColDataLength = 0;
	private int iColDataType = 0;

	db_statement_create_table() {
		oTokens[0] = "CREATE";
		oTokens[1] = "TABLE";
		oTokens[2] = "(";
		oTokens[3] = ")";
		oTokens[4] = "IDENTITY";
		oTokens[5] = ",";
		oTokens[6] = "PRIMARY KEY";
		oTokens[7] = "KEY";
		oTokens[8] = "NOT";
		oTokens[9] = "NULL";
		oTokens[10] = "BIT";
		oTokens[11] = "TINYINT";
		oTokens[12] = "SMALLINT";
		oTokens[13] = "MEDIUMINT";
		oTokens[14] = "INT";
		oTokens[15] = "INTEGER";
		oTokens[16] = "BIGINT";
		oTokens[17] = "REAL";
		oTokens[18] = "DOUBLE";
		oTokens[19] = "FLOAT";
		oTokens[20] = "DECIMAL";
		oTokens[21] = "NUMERIC";
		oTokens[22] = "DATE";
		oTokens[23] = "TIME";
		oTokens[24] = "DATETIME";
		oTokens[25] = "CHAR";
		oTokens[26] = "VARCHAR";

		oRegex[0] = Pattern.compile("(-)?(\\d){1,9}");
		oRegex[1] = Pattern.compile("'([^']|'')*'");
		oRegex[2] = Pattern.compile("[a-zA-Z][0-9a-zA-Z]*");

		oUtilParser = new db_util_parser(oTokens);
	}
	public db_interface_parse_result parse(String sSQL) {
		oRes = new db_parse_result_create_table();
		oColumns = new ArrayList<db_column>();
		oUtilParser.restart(sSQL);
		int iRes = query();

		if (oUtilParser.sQuery.trim().length() > 0 && iRes == 0)
			iRes = -1;

		oRes.set_result(iRes);
		oRes.oColumns = oColumns;
		return oRes;
	}

	public int query() {

		if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[0]))
			return -2;

		if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[1]))
			return -2;

		if(name() == -1)
			return -1;

		oRes.sTableName = oUtilParser.sValue;

		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2]))
			return -1;

		if(collist() == -1)
			return -1;

		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[3]))
			return -1;
		return 0;
	}

	public int collist() {

		if(name() == -1)
			return -1;

		String sColName = oUtilParser.sValue;

		boolean bPrimaryKey = false;
		boolean bNotNull = false;
		boolean bIdentity = false;
		long lIdentitySeed = 0;
		long lIdentityIncrement = 0;

		iColDataLength = 0;
		iColDataType = 0;

		if(datatype() == -1)
			return -1;


		if (iColDataLength == 0)
			iColDataLength = db_util.DB_DATATYPE_INT_LENGTH;

		if (iColDataLength == 0)
			iColDataLength = db_util.DB_DATATYPE_VARCHAR_LENGTH;


		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[4])){
			//Nothing
			bIdentity = true;

			if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2]))
				return -1;
			if(number() == -1)
				return -1;
			lIdentitySeed = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[5]))
				return -1;
			if(number() == -1)
				return -1;
			lIdentityIncrement = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[6])) {
			bPrimaryKey = true;

		}

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[8])){

			if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[9])){

				return -1;	
			}
			bNotNull = true;

		} else {
			if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[9])){
				// Nothing
			}
		}


		if (bPrimaryKey)
			bNotNull = true;

		oColumns.add(new db_column(sColName, iColDataType, iColDataLength, bNotNull, bPrimaryKey, bIdentity, lIdentitySeed, lIdentityIncrement));
		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[5])){
			//Nothing

			if(collist() == -1)
				return -1;
		}
		return 0;
	}

	public int value() {
		if (number() == -1 && string() == -1) {
			//Parse failure
			return -1;
		}
		return 0;
	}

	public int number() {

		if (!oUtilParser.matchReplace(oUtilParser.sQuery, oRegex[0]))
			return -1;
		return 0;
	}

	public int string() {

		if (!oUtilParser.matchReplace(oUtilParser.sQuery, oRegex[1]))
			return -1;
		return 0;
	}

	public int name() {

		if (!oUtilParser.matchReplace(oUtilParser.sQuery, oRegex[2]))
			return -1;
		return 0;
	}

	public int datatype() {


		//if (type_bit() == -1 && type_tinyint() == -1 && type_smallint() == -1 && type_mediumint() == -1 && type_int() == -1 && type_integer() == -1 && type_bigint() == -1 && type_real() == -1 && type_double() == -1 && type_float() == -1 && type_decimal() == -1 && type_numeric() == -1 && type_date() == -1 && type_datetime() == -1 && type_char() == -1 && type_varchar() == -1) {
		if (type_varchar() == -1 && type_int() == -1){
			//Parse failure
			return -1;
		}
		return 0;
	}

	public int type_bit() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[10]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_tinyint() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[11]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_smallint() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[12]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_mediumint() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[13]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_int() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[14]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		iColDataType = db_util.DB_DATATYPE_INT;
		return 0;
	}

	public int type_integer() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[15]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_bigint() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[16]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_real() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[17]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_double() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[18]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_float() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[19]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_decimal() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[20]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_numeric() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[21]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_date() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[22]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_time() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[23]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_datetime() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[24]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_char() {


		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[25]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplace(oUtilParser.sQuery, oTokens[3]))
				return -1;
		}
		return 0;
	}

	public int type_varchar() {		
		if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[26]))
			return -1;

		if (oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[2])){
			//Nothing

			if(number() == -1)
				return -1;
			iColDataLength = Integer.parseInt(oUtilParser.sValue);
			if (!oUtilParser.matchReplaceNoSpace(oUtilParser.sQuery, oTokens[3]))
				return -1;

		}
		iColDataType = db_util.DB_DATATYPE_VARCHAR;
		return 0;

	}
}